home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / xep / xep.c < prev   
C/C++ Source or Header  |  1997-07-22  |  22KB  |  986 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: xep.c,v 1.4 1997/07/09 13:56:58 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
  12.  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33. /*
  34.  *    xep.c
  35.  *
  36.  *    Display pixmap calculated by tiled workers in an X window.
  37.  *
  38.  *    Nov 92 Manchek
  39.  *    Oct 95 Manchek
  40.  */
  41.  
  42.  
  43. #ifdef HASSTDLIB
  44. #include <stdlib.h>
  45. #endif
  46. #include <stdio.h>
  47. #include <math.h>
  48. #include <X11/Xlib.h>
  49. #include <X11/cursorfont.h>
  50. #include <X11/Intrinsic.h>
  51. #include <X11/StringDefs.h>
  52. #include <X11/Shell.h>
  53. #include <X11/Xaw/Label.h>
  54. #include <X11/Xaw/Command.h>
  55. #include <X11/Xaw/Toggle.h>
  56. #include <X11/Xaw/Form.h>
  57. #include <pvm3.h>
  58. #include "../src/bfunc.h"
  59. #include "myalloc.h"
  60. #include "hostc.h"
  61. #include "imp.h"
  62. #include "bars.xbm"
  63. #include "color.xbm"
  64. #include "reset.xbm"
  65. #include "quit.xbm"
  66. #include "into.xbm"
  67. #include "outof.xbm"
  68.  
  69.  
  70. #ifndef    min
  71. #define    min(a,b)    ((a)<(b)?(a):(b))
  72. #endif
  73. #ifndef    max
  74. #define    max(a,b)    ((a)>(b)?(a):(b))
  75. #endif
  76.  
  77.  
  78. static void pick();
  79. static void zoom();
  80. static void redraw();
  81. static void configure();
  82. static void pvm_cb();
  83. static void zin_cb();
  84. static void zout_cb();
  85. static void reset_cb();
  86.  
  87.  
  88. /***************
  89.  **  Globals  **
  90.  **           **
  91.  ***************/
  92.  
  93.  
  94. Display *xDisp;
  95. XtAppContext context;
  96. Widget topLevel = 0;        /* main widget */
  97. Widget thelabel1 = 0;
  98. Widget thelabel2 = 0;
  99. int xScrn;
  100. Window xRootW;
  101. GC rubGc;                /* rubberbox gc */
  102. Cursor crossCr;
  103. struct canvas imCan;    /* just one image for now */
  104.  
  105. char *workerfile = 0;
  106. int nworkers = 0;            /* number of active+idle work servers */
  107. int dobars = 0;                /* label tiles with worker number */
  108.  
  109.  
  110. /***************
  111.  **  Xt Gorp  **
  112.  **           **
  113.  ***************/
  114.  
  115. char canvasTl[] =
  116. "*canvas.translations:\
  117. <Btn1Down>:pick(start)\\n\
  118. <Btn1Motion>:pick(adjust)\\n\
  119. <Btn1Up>:pick(end)\\n\
  120. <Btn2Down>:zoom()\\n\
  121. <Btn3Down>:pick(modify)\\n\
  122. <Btn3Motion>:pick(adjust)\\n\
  123. <Btn3Up>:pick(end)\\n\
  124. <Expose>:redraw()\\n\
  125. <ConfigureNotify>:configure()\\n\
  126. ";
  127.  
  128.  
  129. /* Widget default values */
  130.  
  131. static char *fallbacks[] = {
  132.     "*allowShellResize:true",
  133.     "*quitButton.label:Quit",
  134.     "*recalcButton.label:Redo",
  135.     "*workersButton.label:NewWorkers",
  136.     canvasTl,
  137.     0
  138. };
  139.  
  140. /* To get custom resources */
  141.  
  142. typedef struct {
  143.     Bool mono;            /* force monochrome display */
  144.     Bool fc;            /* use false-color graymap */
  145.     String worker;        /* worker a.out name */
  146.     Bool bars;            /* display processor id bars */
  147.     int n;                /* number of workers */
  148. } app_res_t, *app_resp_t;
  149.  
  150. static app_res_t app_res;
  151.  
  152. static XtResource res_list[] = {
  153.     { "worker", "Worker", XtRString, sizeof(String),
  154.         XtOffset(app_resp_t, worker), XtRString, "mtile" },
  155.     { "monochrome", "Monochrome", XtRBool, sizeof(Bool),
  156.         XtOffset(app_resp_t, mono), XtRString, "off" },
  157.     { "falsecolor", "Falsecolor", XtRBool, sizeof(Bool),
  158.         XtOffset(app_resp_t, fc), XtRString, "on" },
  159.     { "bars", "Bars", XtRBool, sizeof(Bool),
  160.         XtOffset(app_resp_t, bars), XtRString, "off" },
  161.     { "nWorkers", "NWorkers", XtRInt, sizeof(int),
  162.         XtOffset(app_resp_t, n), XtRString, "-1" },
  163. };
  164.  
  165. static XrmOptionDescRec knownargs[] = {
  166.     { "-mono", ".monochrome", XrmoptionNoArg, "on" },
  167.     { "+mono", ".monochrome", XrmoptionNoArg, "off" },
  168.     { "-fc", ".falsecolor", XrmoptionNoArg, "on" },
  169.     { "+fc", ".falsecolor", XrmoptionNoArg, "off" },
  170.     { "-worker", ".worker", XrmoptionSepArg, 0 },
  171.     { "-bars", ".bars", XrmoptionNoArg, "on" },
  172.     { "+bars", ".bars", XrmoptionNoArg, "off" },
  173.     { "-n", ".nWorkers", XrmoptionSepArg, 0 },
  174. };
  175.  
  176. static XtCallbackRec callback[2] = { { 0, 0 }, { 0, 0 } };
  177. static Arg args[16];
  178.  
  179. static XtActionsRec actbl[] = {
  180.     { "pick", pick },
  181.     { "zoom", zoom },
  182.     { "redraw", redraw },
  183.     { "configure", configure },
  184. };
  185.  
  186.  
  187. main(argc, argv)
  188.     int argc;
  189.     char **argv;
  190. {
  191.     int n;
  192.     XGCValues xgcv;
  193.     int *fds;
  194.  
  195.     srandom(getpid());
  196.     n = 0;
  197.     topLevel = XtAppInitialize(&context, "xep",
  198.         knownargs, XtNumber(knownargs),
  199.         &argc, argv,
  200.         fallbacks,
  201.         args, n);
  202.  
  203.     if (argc > 1) {
  204.         for (n = 1; n < argc; n++)
  205.             fprintf(stderr, "unknown option <%s>\n", argv[n]);
  206.         fputs("options:\n", stderr);
  207.         fputs("  -worker filename  set calculation task name\n", stderr);
  208.         fputs("  -/+mono           force mono mode\n", stderr);
  209.         fputs("  -/+fc             use false-color graymap\n", stderr);
  210.         fputs("  -/+bars           display/don't display processor bars\n", stderr);
  211. /*
  212.         fputs("  -n count          set number of workers\n", stderr);
  213. */
  214.         exit(1);
  215.     }
  216.  
  217.     XtGetApplicationResources(topLevel, (caddr_t)&app_res,
  218.         res_list, XtNumber(res_list), 0, 0);
  219.  
  220.     workerfile = app_res.worker;
  221.     dobars = app_res.bars;
  222.  
  223.     pvminit();
  224.  
  225.     XtAppAddActions(context, actbl, XtNumber(actbl));
  226.  
  227.     xDisp = XtDisplay(topLevel);
  228.     xScrn = DefaultScreen(xDisp);
  229.     xRootW = RootWindow(xDisp, xScrn);
  230.  
  231.     crossCr = XCreateFontCursor(xDisp, XC_tcross);
  232.  
  233.     xgcv.function = GXxor;
  234.     xgcv.background = BlackPixel(xDisp, xScrn);
  235. /*
  236.     xgcv.foreground = WhitePixel(xDisp, xScrn) ^ BlackPixel(xDisp, xScrn);
  237. */
  238.     xgcv.foreground = ~0;
  239.     rubGc = XCreateGC(xDisp, xRootW,
  240.             GCBackground|GCForeground|GCFunction, &xgcv);
  241.  
  242.     create_xep_widget();
  243.  
  244.     more_workers();
  245.     do_recalc();
  246.  
  247.     n = pvm_getfds(&fds);
  248. #if 0
  249.     while (n-- > 0) {
  250. #ifdef    DEBUG
  251.         fprintf(stderr, "adding fd %d as input\n", fds[n]);
  252. #endif
  253.         XtAppAddInput(context, fds[n], (XtPointer)XtInputReadMask,
  254.                 pvm_cb, (XtPointer)0);
  255.     }
  256. #endif
  257.     addaninputfile(fds[0], (XtInputId *)0);
  258.  
  259.     XtAppMainLoop(context);
  260. }
  261.  
  262.  
  263. int
  264. addaninputfile(fd, xiip)
  265.     int fd;
  266.     XtInputId *xiip;
  267. {
  268.     XtInputId xii;
  269.  
  270.     xii = XtAppAddInput(context, fd, (XtPointer)XtInputReadMask,
  271.             pvm_cb, (XtPointer)0);
  272.     fprintf(stderr, "addaninputfile() fd %d xii %ld\n", fd, xii);
  273.     if (xiip)
  274.         *xiip = xii;
  275.     return 0;
  276. }
  277.  
  278.  
  279. int
  280. removeaninputfile(xii)
  281.     XtInputId xii;
  282. {
  283.     XtRemoveInput(xii);
  284.     return 0;
  285. }
  286.  
  287.  
  288. static void
  289. pvm_cb(cli, src, id)
  290.     XtPointer cli;
  291.     int *src;
  292.     XtInputId *id;
  293. {
  294.     while (pvm_nrecv(-1, -1) > 0)
  295.         claim_message();
  296. }
  297.  
  298.  
  299. static void
  300. quit_cb(wgt, cli, cd)
  301.     Widget wgt;
  302.     caddr_t cli;
  303.     caddr_t cd;
  304. {
  305.     stop_workers();
  306.     pvm_exit();
  307.     exit(0);
  308. }
  309.  
  310.  
  311. static void
  312. reset_cb(wgt, cli, cd)
  313.     Widget wgt;
  314.     caddr_t cli;
  315.     caddr_t cd;
  316. {
  317.     if (imCan.cn_wd < imCan.cn_ht) {
  318.         imCan.cn_re1 = -2.0;
  319.         imCan.cn_im1 = (-2.0 * imCan.cn_ht) / imCan.cn_wd;
  320.         imCan.cn_re2 = 2.0;
  321.         imCan.cn_im2 = (2.0 * imCan.cn_ht) / imCan.cn_wd;
  322.  
  323.     } else {
  324.         imCan.cn_re1 = (-2.0 * imCan.cn_wd) / imCan.cn_ht;
  325.         imCan.cn_im1 = -2.0;
  326.         imCan.cn_re2 = (2.0 * imCan.cn_wd) / imCan.cn_ht;
  327.         imCan.cn_im2 = 2.0;
  328.     }
  329.     splat_out(imCan.cn_dat, imCan.cn_wd, imCan.cn_ht, 1);
  330.     repaint_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  331.     refresh_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  332.     imCan.cn_x1 = 0;
  333.     imCan.cn_y1 = 0;
  334.     imCan.cn_x2 = 0;
  335.     imCan.cn_y2 = 0;
  336.     do_recalc();
  337. }
  338.  
  339.  
  340. static void
  341. zout_cb(wgt, cli, cd)
  342.     Widget wgt;
  343.     caddr_t cli;
  344.     caddr_t cd;
  345. {
  346.     double d;
  347.  
  348.     d = (imCan.cn_re2 - imCan.cn_re1) / 2;
  349.     imCan.cn_re1 -= d;
  350.     imCan.cn_re2 += d;
  351.     d = (imCan.cn_im2 - imCan.cn_im1) / 2;
  352.     imCan.cn_im1 -= d;
  353.     imCan.cn_im2 += d;
  354.  
  355.     splat_out(imCan.cn_dat, imCan.cn_wd, imCan.cn_ht, 1);
  356.     repaint_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  357.     refresh_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  358.     imCan.cn_x1 = 0;
  359.     imCan.cn_y1 = 0;
  360.     imCan.cn_x2 = 0;
  361.     imCan.cn_y2 = 0;
  362.  
  363.     do_recalc();
  364. }
  365.  
  366.  
  367. static void
  368. zin_cb(wgt, cli, cd)
  369.     Widget wgt;
  370.     caddr_t cli;
  371.     caddr_t cd;
  372. {
  373.     double re1, im1, re2, im2;
  374.     int wd = imCan.cn_wd;
  375.     int ht = imCan.cn_ht;
  376.     int x1 = imCan.cn_x1;
  377.     int y1 = imCan.cn_y1;
  378.     int x2 = imCan.cn_x2;
  379.     int y2 = imCan.cn_y2;
  380.     int t;
  381.  
  382.     if (x1 != x2 && y1 != y2) {
  383.  
  384.         if (x1 > x2) {
  385.             t = x1;
  386.             x1 = x2;
  387.             x2 = t;
  388.         }
  389.         if (y1 > y2) {
  390.             t = y1;
  391.             y1 = y2;
  392.             y2 = t;
  393.         }
  394.         re1 = imCan.cn_re1 + x1 * (imCan.cn_re2 - imCan.cn_re1) / wd;
  395.         im1 = imCan.cn_im1 + y1 * (imCan.cn_im2 - imCan.cn_im1) / ht;
  396.         re2 = re1 + (x2 - x1) * (imCan.cn_re2 - imCan.cn_re1) / wd;
  397.         im2 = im1 + (x2 - x1) * (imCan.cn_im2 - imCan.cn_im1) / wd;
  398.         imCan.cn_re1 = re1;
  399.         imCan.cn_im1 = im1;
  400.         imCan.cn_re2 = re2;
  401.         imCan.cn_im2 = im2;
  402.  
  403.         splat_out(imCan.cn_dat, imCan.cn_wd, imCan.cn_ht, 1);
  404.         repaint_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  405.         refresh_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  406.         imCan.cn_x1 = 0;
  407.         imCan.cn_y1 = 0;
  408.         imCan.cn_x2 = 0;
  409.         imCan.cn_y2 = 0;
  410.  
  411.         do_recalc();
  412.     }
  413. }
  414.  
  415.  
  416. static void
  417. bars_cb(wgt, cli, cd)
  418.     Widget wgt;
  419.     caddr_t cli;
  420.     caddr_t cd;
  421. {
  422.     dobars = !dobars;
  423. }
  424.  
  425.  
  426. static void
  427. color_cb(wgt, cli, cd)
  428.     Widget wgt;
  429.     caddr_t cli;
  430.     caddr_t cd;
  431. {
  432.     app_res.fc = !app_res.fc;
  433.     setup_color(&imCan, app_res.mono, app_res.fc);
  434.     repaint_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  435.     refresh_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  436. }
  437.  
  438.  
  439. create_xep_widget()
  440. {
  441.     Widget box, box2;
  442.     Widget w;
  443.     int n;
  444.     char buf[128];
  445.     Pixmap pm;
  446.  
  447.     n = 0;
  448.     box = XtCreateManagedWidget("box", formWidgetClass, topLevel, args, n);
  449.  
  450.     imCan.cn_re1 = -2.0;
  451.     imCan.cn_im1 = -2.0;
  452.     imCan.cn_re2 = 2.0;
  453.     imCan.cn_im2 = 2.0;
  454.  
  455.     n = 0;
  456.     XtSetArg(args[n], XtNdefaultDistance, 2); n++;
  457.     XtSetArg(args[n], XtNborderWidth, 0); n++;
  458.     XtSetArg(args[n], XtNleft, XtChainLeft); n++;
  459.     XtSetArg(args[n], XtNright, XtChainLeft); n++;
  460.     XtSetArg(args[n], XtNtop, XtChainTop); n++;
  461.     XtSetArg(args[n], XtNbottom, XtChainTop); n++;
  462.     box2 = XtCreateManagedWidget("box3", formWidgetClass, box, args, n);
  463.  
  464.     n = 0;
  465.     XtSetArg(args[n], XtNborderWidth, 0); n++;
  466.     w = XtCreateManagedWidget("hosts", labelWidgetClass,
  467.             box2, args, n);
  468.  
  469.     n = 0;
  470.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  471.     XtSetArg(args[n], XtNborderWidth, 0); n++;
  472.     XtSetArg(args[n], XtNlabel, "0"); n++;
  473. /*
  474.     sprintf(buf, "(%.2e,%.2e) (%.2e,%.2e)", 
  475.             imCan.cn_re1, imCan.cn_im1, imCan.cn_re2, imCan.cn_im2);
  476.     XtSetArg(args[n], XtNlabel, buf); n++;
  477. */
  478.     thelabel1 = w = XtCreateManagedWidget("thelabel1", labelWidgetClass,
  479.             box2, args, n);
  480.  
  481.     n = 0;
  482.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  483.     XtSetArg(args[n], XtNborderWidth, 0); n++;
  484.     w = XtCreateManagedWidget("workers", labelWidgetClass,
  485.             box2, args, n);
  486.  
  487.     n = 0;
  488.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  489.     XtSetArg(args[n], XtNborderWidth, 0); n++;
  490.     XtSetArg(args[n], XtNlabel, "0"); n++;
  491.     thelabel2 = w = XtCreateManagedWidget("thelabel2", labelWidgetClass,
  492.             box2, args, n);
  493.  
  494.     n = 0;
  495.     XtSetArg(args[n], XtNfromVert, box2); n++;
  496.     XtSetArg(args[n], XtNdefaultDistance, 2); n++;
  497.     XtSetArg(args[n], XtNborderWidth, 0); n++;
  498.     XtSetArg(args[n], XtNleft, XtChainLeft); n++;
  499.     XtSetArg(args[n], XtNright, XtChainLeft); n++;
  500.     XtSetArg(args[n], XtNtop, XtChainTop); n++;
  501.     XtSetArg(args[n], XtNbottom, XtChainTop); n++;
  502.     box2 = XtCreateManagedWidget("box2", formWidgetClass, box, args, n);
  503.  
  504.     n = 0;
  505. /*
  506.     XtSetArg(args[n], XtNhorizDistance, 0); n++;
  507.     XtSetArg(args[n], XtNvertDistance, 0); n++;
  508. */
  509.     callback[0].callback = (XtCallbackProc)quit_cb;
  510.     callback[0].closure = (caddr_t)0;
  511.     XtSetArg(args[n], XtNcallback, callback); n++;
  512.     pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
  513.             quit_bits, quit_width, quit_height, 1, 0, 1);
  514.     XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
  515.     w =  XtCreateManagedWidget("quitButton", commandWidgetClass,
  516.             box2, args, n);
  517.  
  518.     n = 0;
  519. /*
  520.     XtSetArg(args[n], XtNhorizDistance, 0); n++;
  521.     XtSetArg(args[n], XtNvertDistance, 0); n++;
  522. */
  523.     callback[0].callback = (XtCallbackProc)reset_cb;
  524.     callback[0].closure = (caddr_t)0;
  525.     XtSetArg(args[n], XtNcallback, callback); n++;
  526.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  527.     pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
  528.             reset_bits, reset_width, reset_height, 1, 0, 1);
  529.     XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
  530.     w =  XtCreateManagedWidget("resetButton", commandWidgetClass,
  531.             box2, args, n);
  532.  
  533.     n = 0;
  534.     callback[0].callback = (XtCallbackProc)zin_cb;
  535.     callback[0].closure = (caddr_t)0;
  536.     XtSetArg(args[n], XtNcallback, callback); n++;
  537.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  538.     pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
  539.             into_bits, into_width, into_height, 1, 0, 1);
  540.     XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
  541.     w =  XtCreateManagedWidget("recalcButton", commandWidgetClass,
  542.             box2, args, n);
  543.  
  544.     n = 0;
  545.     callback[0].callback = (XtCallbackProc)zout_cb;
  546.     callback[0].closure = (caddr_t)0;
  547.     XtSetArg(args[n], XtNcallback, callback); n++;
  548.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  549.     pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
  550.             outof_bits, outof_width, outof_height, 1, 0, 1);
  551.     XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
  552.     w =  XtCreateManagedWidget("zoomoutButton", commandWidgetClass,
  553.             box2, args, n);
  554.  
  555.     n = 0;
  556.     callback[0].callback = (XtCallbackProc)color_cb;
  557.     callback[0].closure = (caddr_t)0;
  558.     XtSetArg(args[n], XtNcallback, callback); n++;
  559.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  560.     XtSetArg(args[n], XtNstate, (app_res.fc ? 1 : 0)); n++;
  561.     pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
  562.             color_bits, color_width, color_height, 1, 0, 1);
  563.     XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
  564.     w =  XtCreateManagedWidget("colorButton", toggleWidgetClass,
  565.             box2, args, n);
  566.  
  567.     n = 0;
  568.     callback[0].callback = (XtCallbackProc)bars_cb;
  569.     callback[0].closure = (caddr_t)0;
  570.     XtSetArg(args[n], XtNcallback, callback); n++;
  571.     XtSetArg(args[n], XtNfromHoriz, w); n++;
  572.     XtSetArg(args[n], XtNstate, dobars); n++;
  573.     pm = XCreatePixmapFromBitmapData(xDisp, xRootW,
  574.             bars_bits, bars_width, bars_height, 1, 0, 1);
  575.     XtSetArg(args[n], XtNbitmap, (XtArgVal)pm); n++;
  576.     w =  XtCreateManagedWidget("barsButton", toggleWidgetClass,
  577.             box2, args, n);
  578.  
  579.     imCan.cn_wd = 200;
  580.     imCan.cn_ht = 200;
  581.  
  582.     n = 0;
  583.     XtSetArg(args[n], XtNleft, XtChainLeft); n++;
  584.     XtSetArg(args[n], XtNright, XtChainRight); n++;
  585.     XtSetArg(args[n], XtNtop, XtChainTop); n++;
  586.     XtSetArg(args[n], XtNbottom, XtChainBottom); n++;
  587.     XtSetArg(args[n], XtNwidth, imCan.cn_wd); n++;
  588.     XtSetArg(args[n], XtNheight, imCan.cn_ht); n++;
  589.     XtSetArg(args[n], XtNfromVert, box2); n++;
  590.     imCan.cn_wgt = XtCreateManagedWidget("canvas", widgetClass,
  591.         box, args, n);
  592.  
  593.     XtRealizeWidget(topLevel);
  594.  
  595.     imCan.cn_win = XtWindow(imCan.cn_wgt);
  596.  
  597. /*
  598.     testothervisual(TrueColor);
  599. */
  600.  
  601.     setup_color(&imCan, app_res.mono, app_res.fc);
  602.     imCan.cn_x1 = 0;
  603.     imCan.cn_y1 = 0;
  604.     imCan.cn_x2 = 0;
  605.     imCan.cn_y2 = 0;
  606.     imCan.cn_zoom = 1;
  607.     imCan.cn_ox = 0;
  608.     imCan.cn_oy = 0;
  609.     imCan.cn_dat = TALLOC(imCan.cn_wd * imCan.cn_ht, u_char, "data");
  610.     splat_out(imCan.cn_dat, imCan.cn_wd, imCan.cn_ht, 1);
  611.     cre_xim(&imCan);
  612.     repaint_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  613.  
  614.     XDefineCursor(xDisp, imCan.cn_win, crossCr);
  615.     return 0;
  616. }
  617.  
  618.  
  619. testothervisual(clas)
  620.     int clas;
  621. {
  622.     XVisualInfo *vinf;
  623.     int nv;
  624.     int i;
  625.     XSetWindowAttributes xswat;
  626.  
  627.     vinf = XGetVisualInfo(xDisp, VisualNoMask, (XVisualInfo*)0, &nv);
  628.     for (i = 0; i < nv; i++)
  629.         if (vinf[i].class == clas)
  630.             break;
  631.     if (i == nv) {
  632.         fprintf(stderr, "couldn't find the right visual\n");
  633.         exit(1);
  634.     }
  635.     fprintf(stderr, "found visual %d: np %d cs %d r 0x%x g 0x%x b 0x%x\n", i,
  636.             vinf[i].depth,
  637.             vinf[i].colormap_size,
  638.             vinf[i].red_mask,
  639.             vinf[i].blue_mask,
  640.             vinf[i].green_mask);
  641.     xswat.colormap = XCreateColormap(xDisp, xRootW, vinf[i].visual, AllocNone);
  642.     xswat.border_pixmap = XCreatePixmap(xDisp, xRootW, 16, 16, 8);
  643.     imCan.cn_win = XCreateWindow(xDisp,
  644.             xRootW,
  645.             0,
  646.             0,
  647.             300,
  648.             300,
  649.             1,
  650.             8,
  651.             InputOutput,
  652.             vinf[i].visual,
  653.             CWColormap|CWBorderPixmap,
  654.             &xswat);
  655.     XMapWindow(xDisp, imCan.cn_win);
  656.     return 0;
  657. }
  658.  
  659.  
  660. setlabel()
  661. {
  662.     int nh;
  663.     struct hostc *hp;
  664.     char buf[64];
  665.  
  666.     hp = 0;
  667.     nh = 0;
  668.     while (hp = host_next(hp))
  669.         nh++;
  670.  
  671.     sprintf(buf, "%d", nh);
  672.     XtSetArg(args[0], XtNlabel, buf);
  673.     XtSetValues(thelabel1, args, 1);
  674.     sprintf(buf, "%d", nworkers);
  675.     XtSetArg(args[0], XtNlabel, buf);
  676.     XtSetValues(thelabel2, args, 1);
  677.     return 0;
  678. }
  679.  
  680.  
  681. static void
  682. configure(wgt, xev, par, nump)
  683.     Widget wgt;
  684.     XEvent *xev;
  685.     String *par;
  686.     int *nump;
  687. {
  688.     int wd, ht;                /* size of new canvas */
  689.     double re1, im1, re2, im2;
  690.     int ox, oy;                /* offset of new image in old */
  691.     u_char *dat;            /* new canvas image */
  692.     u_char *b1, *b2;        /* for copying image data */
  693.     int w, h;
  694.  
  695.     if (xev->type == ConfigureNotify) {
  696.         wd = xev->xconfigure.width;
  697.         ht = xev->xconfigure.height;
  698.  
  699.         ox = (imCan.cn_wd - wd) / 2;
  700.         re1 = imCan.cn_re1
  701.                 + ((imCan.cn_re2 - imCan.cn_re1) * ox) / imCan.cn_wd;
  702.         re2 = imCan.cn_re1
  703.                 + ((imCan.cn_re2 - imCan.cn_re1) * (ox + wd)) / imCan.cn_wd;
  704.         oy = (imCan.cn_ht - ht) / 2;
  705.         im1 = imCan.cn_im1
  706.                 + ((imCan.cn_re2 - imCan.cn_re1) * oy) / imCan.cn_wd;
  707.         im2 = imCan.cn_im1
  708.                 + ((imCan.cn_re2 - imCan.cn_re1) * (oy + ht)) / imCan.cn_wd;
  709.         imCan.cn_re1 = re1;
  710.         imCan.cn_re2 = re2;
  711.         imCan.cn_im1 = im1;
  712.         imCan.cn_im2 = im2;
  713. /*
  714.         fprintf(stderr, "%dx%d  %e,%e  %e,%e\n", wd, ht, re1, im1, re2, im2);
  715.         fprintf(stderr, "%e : %e\n", (re2 - re1) / wd, (im2 - im1) / ht);
  716. */
  717.  
  718.         dat = TALLOC(wd * ht, u_char, "data");
  719.         splat_out(dat, wd, ht, 1);
  720.  
  721.         w = min(imCan.cn_wd, wd);
  722.         h = min(imCan.cn_ht, ht);
  723.         b1 = imCan.cn_dat + max(0, ox) + max(0, oy) * imCan.cn_wd;
  724.         b2 = dat + max(0, -ox) + max(0, -oy) * wd;
  725.         while (h-- > 0) {
  726.             BCOPY(b1, b2, w);
  727.             b1 += imCan.cn_wd;
  728.             b2 += wd;
  729.         }
  730.         MY_FREE(imCan.cn_dat);
  731.  
  732.         imCan.cn_dat = dat;
  733.         imCan.cn_wd = wd;
  734.         imCan.cn_ht = ht;
  735.         imCan.cn_x1 = 0;
  736.         imCan.cn_y1 = 0;
  737.         imCan.cn_x2 = 0;
  738.         imCan.cn_y2 = 0;
  739.         cre_xim(&imCan);
  740.         repaint_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  741.         refresh_region(&imCan, 0, 0, imCan.cn_wd - 1, imCan.cn_ht - 1);
  742.         do_recalc();
  743.     }
  744. }
  745.  
  746.  
  747. static void
  748. redraw(wgt, xev, par, nump)
  749.     Widget wgt;
  750.     XEvent *xev;
  751.     String *par;
  752.     int *nump;
  753. {
  754.     if (xev->type == Expose) {
  755.         rubbox(imCan.cn_win, imCan.cn_x1, imCan.cn_y1,
  756.                 imCan.cn_x2, imCan.cn_y2);
  757.         refresh_region(&imCan, xev->xexpose.x, xev->xexpose.y,
  758.                 xev->xexpose.x + xev->xexpose.width - 1,
  759.                 xev->xexpose.y + xev->xexpose.height - 1);
  760.         rubbox(imCan.cn_win, imCan.cn_x1, imCan.cn_y1,
  761.                 imCan.cn_x2, imCan.cn_y2);
  762.     }
  763. }
  764.  
  765.  
  766. static void
  767. zoom(wgt, xev, par, nump)
  768.     Widget wgt;
  769.     XEvent *xev;
  770.     String *par;
  771.     int *nump;
  772. {
  773.     zin_cb(wgt, (char *)0, (char *)0);
  774. }
  775.  
  776.  
  777. /*    pick()
  778. *
  779. *    s - start
  780. *    a - adjust
  781. *    e - end
  782. *    m - modify
  783. */
  784.  
  785. static void
  786. pick(wgt, xev, par, nump)
  787.     Widget wgt;
  788.     XEvent *xev;
  789.     String *par;
  790.     int *nump;
  791. {
  792.     Window w = XtWindow(wgt);
  793.     int wd = imCan.cn_wd;
  794.     int ht = imCan.cn_ht;
  795.     int x1 = imCan.cn_x1;
  796.     int y1 = imCan.cn_y1;
  797.     int x2 = imCan.cn_x2;
  798.     int y2 = imCan.cn_y2;
  799.     int x, y;
  800.  
  801.     if (*nump == 1 && get_event_xy(xev, &x, &y)) {
  802.         switch (par[0][0]) {
  803.  
  804.         case 's':
  805.             if (x1 != -1)
  806.                 rubbox(w, x1, y1, x2, y2);
  807.             x2 = x1 = x;
  808.             y2 = y1 = y;
  809.             rubbox(w, x1, y1, x2, y2);
  810.             break;
  811.  
  812.         case 'a':
  813.             if (x1 != -1) {
  814.                 rubbox(w, x1, y1, x2, y2);
  815.                 x2 = (abs(y - y1) * wd) / ht;
  816.                 x2 = x - x1 > 0 ? x1 + x2 : x1 - x2;
  817.                 y2 = (abs(x - x1) * ht) / wd;
  818.                 y2 = y - y1 > 0 ? y1 + y2 : y1 - y2;
  819.                 if (abs(x2 - x1) > abs(x - x1))
  820.                     y2 = y;
  821.                 else
  822.                     x2 = x;
  823.                 rubbox(w, x1, y1, x2, y2);
  824.             }
  825.             break;
  826.  
  827.         case 'e':
  828.             if (x1 != -1) {
  829.                 x2 = (abs(y - y1) * wd) / ht;
  830.                 x2 = x - x1 > 0 ? x1 + x2 : x1 - x2;
  831.                 y2 = (abs(x - x1) * ht) / wd;
  832.                 y2 = y - y1 > 0 ? y1 + y2 : y1 - y2;
  833.                 if (abs(x2 - x1) > abs(x - x1))
  834.                     y2 = y;
  835.                 else
  836.                     x2 = x;
  837. /*
  838.     fprintf(stderr, "%d, %d -> %d, %d\n", x1, y1, x2, y2);
  839. */
  840.             }
  841.             break;
  842.  
  843.         case 'm':
  844.             if (x1 != -1) {
  845.                 rubbox(w, x1, y1, x2, y2);
  846.                 if (abs(x - x1) < abs(x - x2))
  847.                     x1 = x2;
  848.                 if (abs(y - y1) < abs(y - y2))
  849.                     y1 = y2;
  850.                 x2 = (abs(y - y1) * wd) / ht;
  851.                 x2 = x - x1 > 0 ? x1 + x2 : x1 - x2;
  852.                 y2 = (abs(x - x1) * ht) / wd;
  853.                 y2 = y - y1 > 0 ? y1 + y2 : y1 - y2;
  854.                 if (abs(x2 - x1) > abs(x - x1))
  855.                     y2 = y;
  856.                 else
  857.                     x2 = x;
  858.                 rubbox(w, x1, y1, x2, y2);
  859.             }
  860.             break;
  861.  
  862.         default:
  863.             break;
  864.         }
  865.         imCan.cn_x1 = x1;
  866.         imCan.cn_y1 = y1;
  867.         imCan.cn_x2 = x2;
  868.         imCan.cn_y2 = y2;
  869.     }
  870. }
  871.  
  872.  
  873. int
  874. get_event_xy(xev, xp, yp)
  875.     XEvent *xev;
  876.     int *xp, *yp;
  877. {
  878.     switch (xev->type) {
  879.     case KeyPress:
  880.     case KeyRelease:
  881.         *xp = xev->xkey.x;
  882.         *yp = xev->xkey.y;
  883.         return 1;
  884.         break;
  885.  
  886.     case ButtonPress:
  887.     case ButtonRelease:
  888.         *xp = xev->xbutton.x;
  889.         *yp = xev->xbutton.y;
  890.         return 1;
  891.         break;
  892.  
  893.     case MotionNotify:
  894.         *xp = xev->xmotion.x;
  895.         *yp = xev->xmotion.y;
  896.         return 1;
  897.         break;
  898.  
  899.     case EnterNotify:
  900.     case LeaveNotify:
  901.         *xp = xev->xcrossing.x;
  902.         *yp = xev->xcrossing.y;
  903.         return 1;
  904.         break;
  905.  
  906.     default:
  907.         return 0;
  908.     }
  909. }
  910.  
  911.  
  912. /*    rubbox()
  913. *
  914. *    Draw a rubberband box XOR in a window.  Call again to undraw.
  915. */
  916.  
  917. rubbox(w, x1, y1, x2, y2)
  918.     Window w;
  919.     int x1, x2, y1, y2;
  920. {
  921.     register int x, y, h, v;
  922.  
  923.     if (x1 < x2)
  924.         { x = x1; h = x2 - x1; }
  925.     else
  926.         { x = x2; h = x1 - x2; }
  927.     if (y1 < y2)
  928.         { y = y1; v = y2 - y1; }
  929.     else
  930.         { y = y2; v = y1 - y2; }
  931.  
  932.     XDrawRectangle(xDisp, w, rubGc, x, y, h, v);
  933.     return 0;
  934. }
  935.  
  936.  
  937. splat_out(ba, wd, ht, dir)
  938.     u_char *ba;
  939.     int wd, ht;
  940.     int dir;
  941. {
  942.     int x = wd;
  943.     int o = 0;
  944.     int n = wd * ht;
  945.  
  946.     dir = dir ? 7 : 1;
  947.     while (--n >= 0) {
  948.         *ba++ = x & 7 ? 0 : 255;
  949.         if (--x <= o) {
  950.             o = (o + dir) & 7;
  951.             x = wd + o;
  952.         }
  953.     }
  954.     return 0;
  955. }
  956.  
  957.  
  958. label_row(y1, y2, n)
  959.     int y1, y2;
  960.     int n;
  961. {
  962.     int wd = imCan.cn_wd;
  963.     int h = y2 - y1;
  964.     int y, x;
  965.     u_char *ba;
  966.     int c = 240;
  967.  
  968.     ba = imCan.cn_dat + y1 * wd;
  969.     for (y = h; y-- > 0; ) {
  970.         BZERO(ba, 21);
  971.         ba += wd;
  972.     }
  973.     ba = imCan.cn_dat + y1 * wd;
  974.     for (y = h - 2; y-- > 0; ) {
  975.         ba += wd;
  976.         for (x = 0; x < 20; x++)
  977.             if (x & 3)
  978.                 ba[x] = (n & (1 << x / 4)) ? 255 : c;
  979.     }
  980.     repaint_region(&imCan, 0, y1, 20, y2 - 1);
  981.     refresh_region(&imCan, 0, y1, 20, y2 - 1);
  982.     return 0;
  983. }
  984.  
  985.  
  986.